home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MEMORY / CHECKCMOS.ARC / !CheckCMOS / c / !Runimage
Text File  |  1993-07-12  |  30KB  |  1,222 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #include "menu.h"
  7. #include "resspr.h"
  8. #include "colourtran.h"
  9. #include "bbc.h"
  10. #include "event.h"
  11. #include "win.h"
  12. #include "dbox.h"
  13. #include "werr.h"
  14. #include "wimp.h"
  15. #include "res.h"
  16. #include "visdelay.h"
  17. #include "template.h"
  18. #include "wimpt.h"
  19. #include "os.h"
  20. #include "swis.h"
  21. #include "kernel.h"
  22. #include "msgs.h"
  23.  
  24. #define CMOS_preferences "<CheckCMOS$Dir>.CMOS_Pref"
  25. #define Program_Settings "<CheckCMOS$Dir>.Settings"
  26.  
  27. char Task_Name[10];
  28.  
  29. typedef int mask;
  30.  
  31. mask prog_settings = 0x00;
  32.  
  33. #define READATTR  5
  34. #define FILEFOUND 1
  35. #define UNUSED(X) (X=X)
  36.  
  37. #define max(X,Y) (((X)>(Y))?(X):(Y))
  38. #define min(X,Y) (((X)<(Y))?(X):(Y))
  39.  
  40. static wimp_w control_handle;              /* window handle */
  41. static wimp_w cmos_items_handle;           /* window handle */
  42.  
  43. typedef char cmos_ram[240];
  44.  
  45. typedef struct
  46. {
  47.   mask         ignore;
  48.   char         name[100];
  49.   int          start_byte;
  50.   int          start_bit;
  51.   int          end_byte;
  52.   int          end_bit;
  53.   int          old_value;
  54.   int          new_value;
  55.   char         *cmos_error;
  56.   BOOL         needs_reset;
  57. } cmos_item;
  58.  
  59. BOOL file_exists ( char *filename )
  60. {
  61.   _kernel_osfile_block finfo;
  62.  
  63.   return (_kernel_osfile(READATTR, filename, &finfo) == FILEFOUND);
  64. }
  65.  
  66. void read_line (FILE *index, char *item, int buffsize)
  67.   int i;    
  68.   char c;
  69.  
  70.   c = fgetc(index);
  71.   for (i=0;(i<(buffsize-1)) && (c!=10) && !feof(index);i++)
  72.     {
  73.       item[i]=c;
  74.       c = fgetc(index);
  75.     }           
  76.   item[i]=0;    
  77. }
  78.  
  79. struct {
  80.   char ignore_name[100];
  81. } ignore_item[32];
  82.   
  83. void initialize_Ignore_masks (void)
  84. {
  85.   int i;
  86.  
  87.   for (i=0;i<=31;i++)
  88.     ignore_item[i].ignore_name[0]=0;
  89. }
  90.  
  91. mask find_or_create_mask ( char *ignore_str )
  92. {                        
  93.   int i;
  94.  
  95.   if (strlen(ignore_str)==0)
  96.     return 0;
  97.  
  98.   for (i=0;i<=31;i++)
  99.     {
  100.       if (strcmp(ignore_item[i].ignore_name,ignore_str)==0)
  101.         return (1<<i);
  102.       if (strlen(ignore_item[i].ignore_name)==0)
  103.         {               
  104.           strcpy (ignore_item[i].ignore_name,ignore_str);
  105.           return (1<<i);
  106.         }
  107.     }
  108.  
  109.   werr (TRUE ,msgs_lookup("ER6:Too many Ignore groups (max 32 unique groups)"));
  110.   exit (0);
  111.   return 0;
  112. }
  113.  
  114. mask find_mask ( char *ignore_str )
  115. {                        
  116.   int i;
  117.  
  118.   if (strlen(ignore_str)==0)
  119.     return 0;
  120.  
  121.   for (i=0;i<=31;i++)
  122.     {
  123.       if (strcmp(ignore_item[i].ignore_name,ignore_str)==0)
  124.         return (1<<i);
  125.     }
  126.  
  127.   return 0;
  128. }
  129.  
  130. char *get_ignore_name ( int ignore_number )
  131. {
  132.   return (ignore_item[ignore_number].ignore_name);
  133. }
  134.  
  135. #define max_cmos_items 200
  136. cmos_item cmos_item_array[max_cmos_items];
  137. cmos_ram current_cmos;
  138. cmos_ram preferred_cmos;
  139.  
  140. void read_cmos (cmos_ram *current_cmos)
  141. {
  142.   int i;
  143.   int temp;
  144.  
  145.   for (i=0;i<=239;i++)
  146.     {
  147.       wimpt_noerr(os_byte(161,&i,&temp));
  148.       (*current_cmos)[i] = temp;
  149.     }
  150. }
  151.  
  152. void modify_cmos (cmos_ram old_cmos, cmos_ram new_cmos)
  153. {
  154.   int i;
  155.   int temp;
  156.  
  157.   visdelay_begin ();
  158.   for (i=0;i<=239;i++)
  159.     {
  160.       if (new_cmos[i] != old_cmos[i])
  161.         {
  162.           temp = new_cmos[i];
  163.           wimpt_noerr(os_byte(162,&i,&temp));
  164.         }
  165.       visdelay_percent (100*i/240);
  166.     }
  167.   visdelay_end ();
  168. }
  169.  
  170. void read_cmos_preferences (cmos_ram *preferred_cmos)
  171. {
  172.   os_filestr f;
  173.  
  174.   f.action = 16;                                     /* load file */
  175.   f.name = CMOS_preferences;
  176.   f.loadaddr = (int)preferred_cmos;
  177.   f.execaddr = 0;
  178.   wimpt_noerr(os_file(&f));
  179. }
  180.  
  181. void save_cmos_preferences (cmos_ram preferred_cmos)
  182. {
  183.   os_filestr f;
  184.  
  185.   f.action = 10;                                    /* save file */
  186.   f.name = CMOS_preferences;
  187.   f.loadaddr = 0xFF2;
  188.   f.start = (int)preferred_cmos;
  189.   f.end   = (int)preferred_cmos+240;
  190.   wimpt_noerr(os_file(&f));
  191. }
  192.  
  193. void read_prog_settings (mask *prog_settings)
  194. {                 
  195.   if (file_exists (Program_Settings))
  196.     {
  197.       FILE *fh;
  198.  
  199.       fh = fopen (Program_Settings,"r");
  200.       while (!feof(fh))
  201.         {
  202.           char name[100];
  203.  
  204.           read_line (fh,name,sizeof(name));
  205.           *prog_settings |= find_mask (name);
  206.         }
  207.       fclose (fh);
  208.     }
  209. }
  210.  
  211. void save_prog_settings (mask prog_settings)
  212. {
  213.   FILE *fh;
  214.   int i;
  215.        
  216.   fh=fopen(Program_Settings,"w");
  217.   for (i=0;i<=31;i++)
  218.     if (prog_settings & (1<<i))
  219.       fprintf (fh,"%s\n",get_ignore_name(i));
  220.   fclose (fh);
  221. }
  222.  
  223.                               
  224. cmos_ram cmos_bits;
  225.  
  226. void initialize_cmos_bits ( void )
  227. {
  228.   int byte;
  229.  
  230.   for (byte=0;byte<=239;byte++)
  231.     cmos_bits[byte] = 0x00;
  232. }
  233.   
  234. void allocate_cmos_bit ( int byte, int bit )
  235. {
  236.   if (cmos_bits[byte] & (1<<bit))
  237.     {
  238.       werr (TRUE ,msgs_lookup("ER2:CMOS Byte %d, Bit %d allocated twice"),byte,bit);
  239.       exit (0);
  240.     }
  241.   cmos_bits[byte] |= (1<<bit);
  242. }
  243.  
  244. void allocate_cmos_byte ( int byte )
  245. {
  246.   if (cmos_bits[byte])
  247.     {
  248.       int bit;
  249.  
  250.       for (bit=0;bit<=7;bit++)
  251.         if (cmos_bits[byte] & (1<<bit))
  252.           {
  253.             werr (TRUE ,msgs_lookup("ER3:CMOS Byte %d allocated twice"),byte);
  254.             exit (0);
  255.           }
  256.     }
  257.   cmos_bits[byte] = 0xFF;
  258. }
  259.  
  260. void allocate_cmos_bits ( int start_byte, int start_bit, int end_byte, int end_bit )
  261. {
  262.   int byte, bit;
  263.                            
  264.   if (start_byte==end_byte)
  265.     {
  266.       if ((start_bit!=0) || (end_bit!=7))
  267.         {
  268.           for (bit=start_bit;bit<=end_bit;bit++)
  269.             allocate_cmos_bit (start_byte,bit);
  270.         }
  271.       else
  272.         allocate_cmos_byte (start_byte);
  273.     }
  274.   else
  275.     {
  276.       if (start_bit!=0)
  277.         for (bit=start_bit;bit<=7;bit++)
  278.           allocate_cmos_bit (start_byte,bit);
  279.       else
  280.         allocate_cmos_byte (start_byte);
  281.  
  282.       for (byte=start_byte+1;byte<=end_byte-1;byte++)
  283.         allocate_cmos_byte (byte);
  284.  
  285.       if (end_bit!=7)
  286.         for (bit=0;bit<=end_bit;bit++)
  287.           allocate_cmos_bit (end_byte,bit);
  288.       else
  289.         allocate_cmos_byte (end_byte);
  290.     }
  291. }
  292.  
  293. void check_cmos_allocations ( void )
  294. {
  295.   int byte, bit;
  296.                            
  297.   for (byte=0;byte<=239;byte++)
  298.     if (cmos_bits[byte]!=0xFF)
  299.       for (bit=0;bit<=7;bit++)
  300.         if ((cmos_bits[byte] & (1<<bit))==0)
  301.           {
  302.             werr (TRUE ,msgs_lookup("ER4:CMOS Byte %d, Bit %d not allocated"),byte,bit);
  303.             exit (0);
  304.           }
  305. }
  306.  
  307. int cmos_item_insert_point = 0;
  308.  
  309. void initialize_cmos_item ( char *ignore_str, char *item_name, int start_byte, int start_bit, int end_byte, int end_bit, BOOL needs_reset )
  310. {        
  311.   mask ignore;
  312.                 
  313.   allocate_cmos_bits (start_byte, start_bit, end_byte, end_bit);
  314.                                             
  315.   ignore = find_or_create_mask (ignore_str);
  316.  
  317.   if (cmos_item_insert_point==max_cmos_items)
  318.     {
  319.       werr (TRUE ,msgs_lookup("ER10:Program limitation - too many CMOS items described"));
  320.       exit (0);
  321.     }
  322.   cmos_item_array[cmos_item_insert_point].ignore      = ignore;
  323.   strcpy (cmos_item_array[cmos_item_insert_point].name,item_name);
  324.   cmos_item_array[cmos_item_insert_point].start_byte  = start_byte;
  325.   cmos_item_array[cmos_item_insert_point].start_bit   = start_bit;
  326.   cmos_item_array[cmos_item_insert_point].end_byte    = end_byte;
  327.   cmos_item_array[cmos_item_insert_point].end_bit     = end_bit;
  328.   cmos_item_array[cmos_item_insert_point].cmos_error  = NULL;
  329.   cmos_item_array[cmos_item_insert_point].needs_reset = needs_reset;
  330.   cmos_item_insert_point++;
  331.   strcpy(cmos_item_array[cmos_item_insert_point].name,"");
  332. }
  333.  
  334. void get_token ( char **token, char **temp)
  335. {
  336.   while (**temp==' ') *temp=*temp+1;
  337.   *token = *temp;
  338.   while ((**temp!=' ')&&(**temp!=0)) *temp=*temp+1;
  339.   if (**temp==' ')
  340.     {
  341.       **temp=0;
  342.       *temp=*temp+1;
  343.     }
  344.   while (**temp==' ') *temp=*temp+1;
  345. }
  346.  
  347. BOOL convert_num ( char *s, int *num, int maxnum )
  348. {
  349.   int i;
  350.  
  351.   for (i=0;i<strlen(s);i++)
  352.     if ((s[i]<'0')||(s[i]>'9'))
  353.       return FALSE;
  354.  
  355.   *num = 0;
  356.   for (i=0;i<strlen(s);i++)
  357.     {
  358.       *num = (*num)*10 + (s[i]-'0');
  359.  
  360.       if (*num>maxnum)
  361.         return FALSE;
  362.     }
  363.  
  364.   return TRUE;
  365. }
  366.  
  367. void uppercase ( char *s )
  368. {
  369.   int i;
  370.   
  371.   for (i=0;i<strlen(s);i++)
  372.     if ((s[i]>='a')&&(s[i]<='z'))
  373.       s[i] = s[i] - 'a' + 'A';
  374. }
  375.  
  376. void uppercase_word ( char *s )
  377. {
  378.   int i;
  379.   
  380.   for (i=0;(i<strlen(s)) && (s[i]!=':');i++)
  381.     if ((s[i]>='a')&&(s[i]<='z'))
  382.       s[i] = s[i] - 'a' + 'A';
  383. }
  384.  
  385. char *token_lookup (char *s)
  386. {
  387.   static char temp[256];
  388.   char *msgptr;
  389.  
  390.   msgptr = msgs_lookup(s);
  391.   strcpy(temp,msgptr);
  392.   uppercase(temp);
  393.   return temp;
  394. }
  395.  
  396. void parse_location_line (char *line, int *start_byte, int *start_bit, int *end_byte, int *end_bit, BOOL *error)
  397. {     
  398.   char *temp = line;          
  399.   char *token;
  400.   BOOL first_bit_specified = FALSE;
  401.                  
  402.   uppercase(line);
  403.  
  404.   /* BYTE <num> [BIT <num>] [TO [BYTE <num>] [BIT <num>]] */
  405.   /* TO must be followed by a BYTE or BIT */
  406.   /* Anomily: BYTE 5 BIT 3 ... means only bit 3 */
  407.  
  408.   *error=FALSE;
  409.   get_token (&token,&temp);
  410.   if (strcmp(token,token_lookup("LANG1:BYTE"))==0)
  411.     {
  412.       get_token (&token,&temp);
  413.       if (!convert_num (token,start_byte,240))
  414.         {
  415.           *error = TRUE;
  416.           return;
  417.         }
  418.       get_token (&token,&temp);
  419.       if (strcmp(token,token_lookup("LANG2:BIT"))==0)
  420.         {
  421.           get_token (&token,&temp);
  422.           if (!convert_num (token,start_bit,7))
  423.             {
  424.               *error = TRUE;
  425.               return;
  426.             }
  427.           get_token (&token,&temp);
  428.           first_bit_specified = TRUE;
  429.         }
  430.       else
  431.         *start_bit = 0;
  432.       if (strcmp(token,token_lookup("LANG3:TO"))==0)
  433.         {
  434.           get_token (&token,&temp);
  435.           if (strcmp(token,token_lookup("LANG1:BYTE"))==0)
  436.             {
  437.               get_token (&token,&temp);
  438.               if (!convert_num (token,end_byte,240))
  439.                 {
  440.                   *error = TRUE;
  441.                   return;
  442.                 }
  443.               get_token (&token,&temp);
  444.               if (strcmp(token,token_lookup("LANG2:BIT"))==0)
  445.                 {
  446.                   get_token (&token,&temp);
  447.                   if (!convert_num (token,end_bit,7))
  448.                     {
  449.                       *error = TRUE;
  450.                       return;
  451.                     }
  452.                   get_token (&token,&temp);
  453.                 }
  454.               else
  455.                 *end_bit = 7;
  456.             }
  457.           else
  458.           if (strcmp(token,token_lookup("LANG2:BIT"))==0)
  459.             {
  460.               *end_byte = *start_byte;
  461.               get_token (&token,&temp);
  462.               if (!convert_num (token,end_bit,7))
  463.                 {
  464.                   *error = TRUE;
  465.                   return;
  466.                 }
  467.               get_token (&token,&temp);
  468.             }
  469.           else
  470.             {
  471.               *error = TRUE;
  472.               return;
  473.             }
  474.         }
  475.       else
  476.         {
  477.           *end_byte = *start_byte;   
  478.           if (first_bit_specified)
  479.             *end_bit = *start_bit;
  480.           else
  481.             *end_bit = 7;    
  482.         }
  483.       if (strlen(token)!=0)
  484.         *error = TRUE;
  485.     }
  486.   else
  487.     *error = TRUE;
  488. }
  489.  
  490. void trim_ends (char *line)
  491. {
  492.   char *start = line;
  493.   char *end;   
  494.  
  495.   while (*start==' ') start++;
  496.  
  497.   memmove (line,start,strlen(start)+1);
  498.  
  499.   end = line+strlen(line)-1;
  500.   while (*end==' ') *end-- = 0;
  501. }
  502.                                                             
  503. int os_version (void)
  504. {
  505.   _kernel_swi_regs reg;
  506.  
  507.   reg.r[0] = 129;  /* Read keyboard for information  */
  508.   reg.r[1] = 0;    /* Read the OS version identifier */
  509.   reg.r[2] = 0xFF;  
  510.   _kernel_swi (OS_Byte,®,®);
  511.  
  512.   return reg.r[1];
  513. }
  514.  
  515. void os_not_supported (void)
  516. {
  517.   werr (TRUE ,msgs_lookup("ER9:Risc OS 2.00 to Risc OS 3.11 only supported"));
  518.   exit (0);
  519. }
  520.  
  521. void init_cmos_array (void)
  522. {
  523.   FILE *fh;
  524.   int LineNo = 0;
  525.   char CMOS_Table[50];
  526.  
  527.   switch (os_version())
  528.     {
  529.       case 0xA0 : os_not_supported();
  530.       case 0xA1 : 
  531.       case 0xA2 : sprintf (CMOS_Table,"<CheckCMOS$Dir>.RISCOS2"); break;
  532.       case 0xA3 : 
  533.       case 0xA4 : sprintf (CMOS_Table,"<CheckCMOS$Dir>.RISCOS3"); break;
  534.       default   : os_not_supported();
  535.     }
  536.  
  537.   initialize_cmos_bits();
  538.   initialize_Ignore_masks();
  539.  
  540.   if (!file_exists (CMOS_Table))
  541.     {
  542.       werr (TRUE ,msgs_lookup("ER7:CMOS Table could not be found (to create one see docs)"));
  543.       exit (0);
  544.     }
  545.  
  546.   fh = fopen (CMOS_Table,"r");
  547.   while (!feof(fh))
  548.     {
  549.       typedef struct
  550.        {
  551.          char group[100];
  552.          char name[100];
  553.          int  start_byte;
  554.          int  start_bit;
  555.          int  end_byte;
  556.          int  end_bit;
  557.          BOOL needs_reset;
  558.        } cmos_desc;
  559.  
  560.       char line[100]="";     
  561.       cmos_desc new_item;
  562.       BOOL error;
  563.  
  564.       *new_item.group=0;
  565.       new_item.needs_reset=TRUE;
  566.       
  567.       while ((strlen(line)==0) && !feof(fh))
  568.         {
  569.           read_line (fh,line,sizeof(line));
  570.           LineNo++;
  571.         }                                   
  572.  
  573.       if (!feof(fh))
  574.         {
  575.           parse_location_line (line,&new_item.start_byte,&new_item.start_bit,&new_item.end_byte,&new_item.end_bit,&error);
  576.           if (error)
  577.             {
  578.               werr (TRUE ,msgs_lookup("ER8:Parse Error in CMOS_Table, line %d"),LineNo);
  579.               exit (0);
  580.             }
  581.           read_line (fh,new_item.name,sizeof(new_item.name));
  582.           LineNo++;
  583.           read_line (fh,line,sizeof(line));
  584.           LineNo++;
  585.           trim_ends (line);
  586.           uppercase_word (line);
  587.           while (strcmp(line,token_lookup("LANG7:End"))!=0)
  588.             {
  589.               if ((strlen(line)==0)&&feof(fh))
  590.                 {
  591.                   werr (TRUE ,msgs_lookup("ER8:Parse Error in CMOS_Table, line %d"),LineNo);
  592.                   exit (0);
  593.                 }                 
  594.               
  595.               {
  596.                 if (strncmp(line,token_lookup("LANG4:Group"),strlen(token_lookup("LANG4:Group")))==0)
  597.                   {
  598.                     strcpy (new_item.group,line+strlen(token_lookup("LANG4:Group"))+1);
  599.                     trim_ends (new_item.group);
  600.                   }
  601.                 else
  602.                 if (strcmp(line,token_lookup("LANG6:Needs reset to take effect"))==0)
  603.                   new_item.needs_reset = TRUE;
  604.                 else
  605.                 if (strcmp(line,token_lookup("LANG5:Has instant effect"))==0)
  606.                   new_item.needs_reset = FALSE;
  607.                 else
  608.                   {
  609.                     werr (TRUE ,msgs_lookup("ER8:Parse Error in CMOS_Table, line %d"),LineNo);
  610.                     exit (0);
  611.                   }
  612.               }
  613.               read_line (fh,line,sizeof(line));
  614.               trim_ends (line);
  615.               uppercase_word (line);
  616.               LineNo++;
  617.             }
  618.  
  619.           initialize_cmos_item (new_item.group,new_item.name,new_item.start_byte,new_item.start_bit,new_item.end_byte,new_item.end_bit,new_item.needs_reset);
  620.         }
  621.     }
  622.   fclose (fh);
  623.   
  624.   check_cmos_allocations();                                                                        
  625. }
  626.  
  627. void perform_cmos_check ( BOOL *cmos_changed )
  628. {
  629.   int i;
  630.  
  631.   *cmos_changed = FALSE;
  632.   for (i=0;i<240;i++)
  633.     if (current_cmos[i] != preferred_cmos[i])
  634.       *cmos_changed = TRUE;
  635. }
  636.  
  637. void set_error_message ( int target_item, char *message )
  638. {
  639.   int item;
  640.  
  641.   if ( prog_settings & cmos_item_array[target_item].ignore )
  642.     return;
  643.  
  644.   for (item=0;strlen(cmos_item_array[item].name)!=0;item++)
  645.     if (strcmp(cmos_item_array[item].cmos_error,message)==0)
  646.       return;
  647.  
  648.   cmos_item_array[target_item].cmos_error = message;
  649. }
  650.  
  651.  
  652. void collate_changes_to_cmos (cmos_ram current_cmos, cmos_ram preferred_cmos, int *changes)
  653. {
  654.   int item;
  655.  
  656.   for (item=0;strlen(cmos_item_array[item].name)!=0;item++)
  657.     {
  658.       int byte, bit;
  659.       BOOL ok = TRUE;
  660.       char mask;
  661.  
  662.       if (cmos_item_array[item].start_byte == cmos_item_array[item].end_byte)
  663.         {        
  664.           mask = 0;
  665.           for (bit=cmos_item_array[item].start_bit;bit<=cmos_item_array[item].end_bit;bit++)
  666.             mask |= (1<<bit);
  667.           if ((preferred_cmos[cmos_item_array[item].start_byte] & mask) != (current_cmos[cmos_item_array[item].start_byte] & mask))
  668.             ok = FALSE;
  669.         }
  670.       else
  671.         {
  672.           mask = 0;
  673.           for (bit=cmos_item_array[item].start_bit;bit<=7;bit++)
  674.             mask |= (1<<bit);
  675.           if ((preferred_cmos[cmos_item_array[item].start_byte] & mask) != (current_cmos[cmos_item_array[item].start_byte] & mask))
  676.             ok = FALSE;
  677.  
  678.           for (byte=cmos_item_array[item].start_byte+1;byte<=cmos_item_array[item].end_byte-1;byte++)
  679.             if (preferred_cmos[byte] != current_cmos[byte])
  680.               ok = FALSE;
  681.  
  682.           mask = 0;
  683.           for (bit=0;bit<=cmos_item_array[item].end_bit;bit++)
  684.             mask |= (1<<bit);
  685.           if ((preferred_cmos[cmos_item_array[item].end_byte] & mask) != (current_cmos[cmos_item_array[item].end_byte] & mask))
  686.             ok = FALSE;
  687.         }
  688.  
  689.       cmos_item_array[item].cmos_error = NULL;
  690.       if (!ok)
  691.         set_error_message (item,cmos_item_array[item].name);
  692.     }
  693.  
  694.   /* count the changes */
  695.   *changes = 0;
  696.   for (item=0;strlen(cmos_item_array[item].name)!=0;item++)
  697.     if (cmos_item_array[item].cmos_error)
  698.       *changes = *changes + 1;
  699. }
  700.  
  701. void get_screen_size (int *x, int *y)
  702. {
  703.   _kernel_swi_regs reg;
  704.   int X, Y, XE, YE;
  705.  
  706.   reg.r[0] = -1;
  707.   reg.r[1] = 11;
  708.   _kernel_swi (OS_ReadModeVariable,®,®);
  709.   X = reg.r[2] + 1;
  710.  
  711.   reg.r[0] = -1;
  712.   reg.r[1] = 12;
  713.   _kernel_swi (OS_ReadModeVariable,®,®);
  714.   Y = reg.r[2] + 1;
  715.  
  716.   reg.r[0] = -1;
  717.   reg.r[1] = 4;
  718.   _kernel_swi (OS_ReadModeVariable,®,®);
  719.   XE = 1<<reg.r[2];
  720.  
  721.   reg.r[0] = -1;
  722.   reg.r[1] = 5;
  723.   _kernel_swi (OS_ReadModeVariable,®,®);
  724.   YE = 1<<reg.r[2];
  725.  
  726.   *x = X*XE;
  727.   *y = Y*YE;
  728. }
  729.  
  730. void redo_viewer(wimp_redrawstr r)
  731. {
  732.   int item;
  733.   int x, y;
  734.  
  735.   x = r.box.x0-r.scx+10;
  736.   y = r.box.y1-r.scy-10;
  737.  
  738.   for (item=0;strlen(cmos_item_array[item].name)!=0;item++)
  739.     if (cmos_item_array[item].cmos_error)
  740.       {
  741.         bbc_move (x, y);
  742.         printf ("%s",cmos_item_array[item].cmos_error);
  743.         y = y - 36;
  744.       }
  745. }
  746.  
  747.  
  748. void redraw_viewer (wimp_openstr o)
  749. {
  750.   wimp_redrawstr r;
  751.   BOOL more;                
  752.  
  753.   r.w = o.w;
  754.   wimpt_noerr(wimp_redraw_wind(&r, &more));
  755.           
  756.   while (more)
  757.   {  
  758.      if (r.w==cmos_items_handle)
  759.        redo_viewer(r);                
  760.      wimpt_noerr(wimp_get_rectangle(&r, &more));
  761.   }
  762. }
  763.  
  764. void get_input_focus(void)
  765. {
  766.   wimp_caretstr caret;
  767.  
  768.   caret.w = control_handle;
  769.   caret.i = -1;
  770.   caret.x = 0;
  771.   caret.y = 0;
  772.   caret.height = 1<<25;
  773.   caret.index = -1;
  774.       
  775.   wimpt_complain(wimp_set_caret_pos(&caret));
  776. }
  777.  
  778.  
  779. void recollate_changes_to_cmos ( void )
  780. {
  781.   wimp_wind *w;
  782.   wimp_redrawstr r;
  783.   int cmos_changes;
  784.  
  785.   collate_changes_to_cmos (current_cmos,preferred_cmos,&cmos_changes);  
  786.  
  787.   w = template_syshandle("CMOS_Items");
  788.  
  789.   r.w = cmos_items_handle;
  790.   r.box.x0 = w->ex.x0;
  791.   r.box.x1 = w->ex.x1;
  792.   r.box.y0 = min(w->box.y0-w->box.y1+2,-(10+(cmos_changes*36)));
  793.   r.box.y1 = 0;
  794.  
  795.   wimpt_complain (wimp_set_extent(&r));
  796.  
  797.   {
  798.     wimp_wstate s;
  799.  
  800.     wimpt_noerr(wimp_get_wind_state(cmos_items_handle, &s));
  801.     wimpt_noerr(wimp_open_wind(&s.o));
  802.   }
  803.  
  804.   wimpt_noerr(wimp_force_redraw(&r));
  805.  
  806.  
  807. /*
  808.   r.w = control_handle;
  809.   dbox_setfield ((dbox)(r.w),3,"REBOOT");
  810.   wimpt_noerr(wimp_force_redraw(&r));
  811. */
  812. }
  813.  
  814. /****************************** MENU **************************************/
  815.  
  816. menu CMOS_CHK_Menu;
  817.  
  818. typedef enum { menu_INFO=1,
  819.                menu_IGNORE,
  820.                menu_SAVE
  821.              } main_menu_choices;
  822.  
  823. menu Ignore_Menu;
  824.  
  825. void set_menu_flags ()
  826.   int i;
  827.                                                       
  828.   for (i=0;i<=31;i++)
  829.     {
  830.       if (strlen(get_ignore_name(i))!=0)
  831.         menu_setflags (Ignore_Menu, i+1, (prog_settings & (1<<i)), FALSE);
  832.     }
  833. }
  834.  
  835. void MenuEventHandler (void *handle, char *hit)
  836. {                                    
  837.   UNUSED (handle);
  838.  
  839.   switch(hit[0])
  840.     {
  841.       case menu_INFO:
  842.         {
  843.           dbox  InfoDbox;
  844.  
  845.           if ((InfoDbox = dbox_new("ProgInfo")) != NULL)
  846.           {
  847.             dbox_setfield(InfoDbox,0,Task_Name);
  848.             dbox_setfield(InfoDbox,1,msgs_lookup("DESC:CMOS Ram controller"));
  849.             dbox_setfield(InfoDbox,2,"Paul Denize");
  850.             dbox_setfield(InfoDbox,3,msgs_lookup("VERS:Version Unknown"));
  851.             dbox_show(InfoDbox);
  852.             dbox_fillin(InfoDbox);
  853.             dbox_dispose(&InfoDbox);
  854.           }
  855.         }
  856.         break;
  857.  
  858.       case menu_IGNORE:
  859.         {
  860.           prog_settings ^= (1<<(hit[1]-1));
  861.           set_menu_flags ();
  862.           recollate_changes_to_cmos ();
  863.         }
  864.         break;
  865.  
  866.       case menu_SAVE:
  867.         save_prog_settings (prog_settings);       
  868.         break;
  869.     }
  870.  
  871. }
  872.  
  873.  
  874. typedef enum { Continue_Icon    = 1,
  875.                Save_Icon,
  876.                Reset_Icon
  877.              } cmos_control_window_icons;
  878.  
  879. void main_buttonpress(wimp_mousestr *m)
  880. {
  881.   switch (m->bbits & (wimp_BLEFT|wimp_BMID|wimp_BRIGHT))
  882.     {
  883.       case wimp_BLEFT:
  884.         switch (m->i)
  885.           {
  886.             case Continue_Icon:
  887.               exit(0);
  888.               break;
  889.             case Save_Icon:
  890.               save_cmos_preferences (current_cmos);
  891.               exit(0);
  892.               break;
  893.             case Reset_Icon:
  894.               { 
  895.                 BOOL reset_required = FALSE;
  896.                 int item;
  897.                 os_error err;                  
  898.                 wimp_errflags errflags = (wimp_EOK + 16); 
  899.                  char mess[100];
  900.  
  901.  
  902.                 for (item=0;(strlen(cmos_item_array[item].name)!=0) && (!reset_required);item++)
  903.                   reset_required = ((cmos_item_array[item].cmos_error) && (cmos_item_array[item].needs_reset));
  904.  
  905.                 modify_cmos (current_cmos,preferred_cmos);
  906.  
  907.                 err.errnum = 0;
  908.                 sprintf (mess,"%s %s",msgs_lookup("MESS:Message from"),Task_Name);
  909.                 if (reset_required) 
  910.                   strcpy(err.errmess,msgs_lookup("MSG1:CMOS has been altered, Some settings may require a reset before they will take effect"));
  911.                 else
  912.                   strcpy(err.errmess,msgs_lookup("MSG2:CMOS has been altered, No reset required"));
  913.                 wimpt_noerr(wimp_reporterror (&err,errflags,mess));
  914.                 exit(0);
  915.               }
  916.               break;
  917.           }
  918.         get_input_focus();
  919.         break;
  920.     }
  921. }
  922.      
  923. #define Escape_Key 0x1B
  924. #define Return_Key 0x0D
  925.  
  926. void main_keypress ( int chcode )
  927. {
  928.   switch (chcode)
  929.     {
  930.       case Escape_Key:
  931.         exit(0);
  932.         break;
  933.       case Return_Key:
  934.         exit(0);
  935.         break;
  936.     }
  937.   wimp_processkey (chcode);
  938. }
  939.  
  940. void send_help_reply (wimp_msgstr* msg)
  941. {
  942.   msg->hdr.your_ref = msg->hdr.my_ref;
  943.   msg->hdr.action = wimp_MHELPREPLY;
  944.   msg->hdr.size = 256;
  945.   
  946.   switch (msg->data.helprequest.m.i)
  947.   {
  948.     case 1: /* Continue icon */
  949.       sprintf(msg->data.helpreply.text, msgs_lookup("HE1:This is the CONTINUE button.|M\\Scontinue with system as it is."));
  950.       break;
  951.  
  952.     case 2: /* Save icon */
  953.       sprintf(msg->data.helpreply.text, msgs_lookup("HE2:This is the SAVE button.|M\\Ssave current settings as your preferred settings."));
  954.       break;
  955.  
  956.     case 3: /* Reset icon */
  957.       sprintf(msg->data.helpreply.text, msgs_lookup("HE3:This is the RESET button.|M\\Sreset the CMOS to the stored preferred settings."));
  958.       break;        
  959.  
  960.     default:
  961.       sprintf(msg->data.helpreply.text, msgs_lookup("HE4:This is the Check_CMOS alert window.|MCMOS items that are not set to the values you selected as preferred are indicated here."));
  962.       break;
  963.    }
  964.   wimpt_noerr(wimp_sendmessage(wimp_ESEND, msg, msg->hdr.task));
  965. }
  966.  
  967. void recentre_windows ( void )
  968. {
  969.   wimp_wstate s;
  970.  
  971.   wimpt_noerr(wimp_get_wind_state(control_handle, &s));
  972.   {
  973.     int screenx, screeny;
  974.     
  975.     get_screen_size (&screenx, &screeny);
  976.     {
  977.       int middle1;
  978.       int middle2;
  979.       int dx;
  980.       int dy;
  981.       
  982.       middle1 = screenx/2;
  983.       middle2 = s.o.box.x0 + ((s.o.box.x1-s.o.box.x0)/2);
  984.       dx = middle1 - middle2;
  985.  
  986.       middle1 = screeny/2;
  987.       middle2 = s.o.box.y0 + ((s.o.box.y1-s.o.box.y0)/2);
  988.       dy = middle1 - middle2;
  989.  
  990.       s.o.box.x0 += dx;
  991.       s.o.box.x1 += dx;
  992.       s.o.box.y0 += dy;
  993.       s.o.box.y1 += dy;
  994.     }
  995.   }
  996.   wimpt_noerr(wimp_open_wind(&s.o));
  997.  
  998.   {
  999.     wimp_wstate s2;
  1000.      
  1001.     wimpt_noerr(wimp_get_wind_state(cmos_items_handle, &s2));
  1002.     {
  1003.       int middle1 = s.o.box.x0 + ((s.o.box.x1-s.o.box.x0)/2);
  1004.       int middle2 = s2.o.box.x0 + ((s2.o.box.x1-s2.o.box.x0)/2);
  1005.       int dx = middle1 - middle2 - 20;
  1006.       int dy = 116 - (s2.o.box.y0 - s.o.box.y0);
  1007.              
  1008.       s2.o.box.x0 += dx;
  1009.       s2.o.box.x1 += dx;
  1010.       s2.o.box.y0 += dy;
  1011.       s2.o.box.y1 += dy;  
  1012.     }
  1013.     wimpt_noerr(wimp_open_wind(&s2.o));
  1014.   }                  
  1015. }
  1016.  
  1017. void control_event_handler(wimp_eventstr *e, void *handle)    /* event handler */
  1018. {
  1019.  
  1020.   handle = handle;
  1021.  
  1022.   switch (e->e)
  1023.   {
  1024.     case wimp_ENULL:
  1025.       event_setmask(event_getmask()|wimp_EMNULL);
  1026.       recentre_windows();
  1027.       break;
  1028.  
  1029.     case wimp_EREDRAW:
  1030.       redraw_viewer(e->data.o);
  1031.       break;
  1032.  
  1033.     case wimp_EOPEN:
  1034.       {
  1035.         wimp_wstate s;
  1036.         
  1037.         if (e->data.o.w == control_handle)
  1038.           {
  1039.             wimpt_noerr(wimp_get_wind_state(cmos_items_handle, &s));
  1040.             s.o.behind = e->data.o.behind;
  1041.  
  1042.             {
  1043.               int middle1 = e->data.o.box.x0 + ((e->data.o.box.x1-e->data.o.box.x0)/2);
  1044.               int middle2 = s.o.box.x0 + ((s.o.box.x1-s.o.box.x0)/2);
  1045.               int dx = middle1 - middle2 - 20;
  1046.               int dy = 116 - (s.o.box.y0 - e->data.o.box.y0);
  1047.              
  1048.               s.o.box.x0 += dx;
  1049.               s.o.box.x1 += dx;
  1050.               s.o.box.y0 += dy;
  1051.               s.o.box.y1 += dy;  
  1052.             }                  
  1053.  
  1054.             wimpt_noerr(wimp_open_wind(&s.o));
  1055.  
  1056.             e->data.o.behind = cmos_items_handle;
  1057.           }
  1058.         else
  1059.           {
  1060.             wimpt_noerr(wimp_get_wind_state(cmos_items_handle, &s));
  1061.             e->data.o.box = s.o.box; /* not Movable */
  1062.             e->data.o.behind = s.o.behind; /* non Orderable */
  1063.           }
  1064.        }
  1065.       wimpt_noerr(wimp_open_wind(&e->data.o));
  1066.       break;
  1067.  
  1068.     case wimp_ECLOSE:
  1069.       win_register_event_handler(control_handle, 0, 0);
  1070.       wimpt_noerr(wimp_delete_wind(control_handle));
  1071.       win_activedec();
  1072.       break;
  1073.  
  1074.     case wimp_EBUT:   
  1075.       main_buttonpress(&e->data.but.m);
  1076.       break;
  1077.  
  1078.     case wimp_EKEY:
  1079.       main_keypress(e->data.key.chcode);
  1080.       break;
  1081.  
  1082.     case wimp_ESEND:
  1083.     case wimp_ESENDWANTACK:    
  1084.       switch(e->data.msg.hdr.action)
  1085.       {
  1086.         case wimp_MMODECHANGE:
  1087.           event_setmask(event_getmask()&~wimp_EMNULL);
  1088.           break;                    
  1089.  
  1090.         case wimp_MHELPREQUEST:
  1091.           send_help_reply(&e->data.msg);
  1092.           break;
  1093.       }
  1094.    }
  1095. }
  1096.  
  1097. void get_task_name (char *name)
  1098. {
  1099.   char obey_dir[256];
  1100.   char *leaf;
  1101.  
  1102.   os_read_var_val("Obey$Dir",obey_dir,sizeof(obey_dir));
  1103.  
  1104.   leaf = obey_dir;
  1105.  
  1106.   while (strchr(leaf,'.')!=0)
  1107.     {
  1108.       leaf = strchr(leaf,'.')+2;
  1109.     }
  1110.      
  1111.   strcpy(name,leaf);
  1112. }
  1113.  
  1114. void alert_user_of_changes (void)
  1115. {
  1116.   int cmos_changes;
  1117.  
  1118.   init_cmos_array ();
  1119.  
  1120.   read_prog_settings (&prog_settings);
  1121.  
  1122.   collate_changes_to_cmos (current_cmos,preferred_cmos,&cmos_changes);
  1123.  
  1124.   if (cmos_changes)
  1125.    {
  1126.     wimp_wind *w;
  1127.     wimp_wstate s;
  1128.  
  1129.     get_task_name (Task_Name);
  1130.     wimpt_init(Task_Name);
  1131.     resspr_init();
  1132.     template_init();
  1133.  
  1134.     if ((w = template_syshandle("CMOS_Items")) == 0)
  1135.       werr (FALSE, msgs_lookup ("ER1:Template \"CMOS_Items\" not found"));
  1136.  
  1137.     w->ex.y0 = min(w->box.y0-w->box.y1+2,-(10+(cmos_changes*36)));
  1138.     w->ex.y1 = 0;
  1139.  
  1140.     wimpt_noerr(wimp_create_wind(w, &cmos_items_handle));
  1141.     wimpt_noerr(wimp_get_wind_state(cmos_items_handle, &s));
  1142.     s.o.behind = -1;
  1143.     wimpt_noerr(wimp_open_wind(&s.o));
  1144.  
  1145.     if ((w = template_syshandle("Control")) == 0)
  1146.       werr (FALSE, msgs_lookup ("ER0:Template \"Control\" not found"));
  1147.  
  1148.     wimpt_noerr(wimp_create_wind(w, &control_handle));
  1149.     wimpt_noerr(wimp_get_wind_state(control_handle, &s));
  1150.     s.o.behind = cmos_items_handle;
  1151.     wimpt_noerr(wimp_open_wind(&s.o));
  1152.                                   
  1153.     recentre_windows();
  1154.  
  1155.     win_claim_unknown_events(cmos_items_handle);
  1156.     win_claim_unknown_events(control_handle);
  1157.     win_activeinc();
  1158.  
  1159.     win_register_event_handler(control_handle, control_event_handler, 0);
  1160.     win_register_event_handler(cmos_items_handle, control_event_handler, 0);
  1161.     {                                      
  1162.       char menustr[200];
  1163.       sprintf (menustr,">%s,%s,%s", msgs_lookup("MENU0:Info"), 
  1164.                                     msgs_lookup("MENU1:Ignore"), 
  1165.                                     msgs_lookup("MENU2:Save Options"));
  1166.       CMOS_CHK_Menu = menu_new(Task_Name,menustr);
  1167.     }
  1168.     {                                      
  1169.       char menustr[200] = "";
  1170.       int i;
  1171.    
  1172.       for(i=0;i<=31;i++)
  1173.         {
  1174.           char *ignore_name;
  1175.  
  1176.           ignore_name = get_ignore_name(i);
  1177.           if (strlen(ignore_name)!=0)
  1178.             {
  1179.               strcat (menustr,",");
  1180.               strcat(menustr,ignore_name);
  1181.             }
  1182.         }
  1183.       Ignore_Menu = menu_new(msgs_lookup("MENU1:Ignore"),menustr);
  1184.     }
  1185.     menu_submenu (CMOS_CHK_Menu,menu_IGNORE,Ignore_Menu);
  1186.     set_menu_flags ();
  1187.     event_attachmenu(cmos_items_handle, CMOS_CHK_Menu, MenuEventHandler, NULL); 
  1188.     event_attachmenu(control_handle, CMOS_CHK_Menu, MenuEventHandler, NULL); 
  1189.  
  1190.     get_input_focus();
  1191.  
  1192.     event_setmask(event_getmask()|wimp_EMPTRLEAVE
  1193.                                  |wimp_EMPTRENTER);
  1194.  
  1195.     while (TRUE)
  1196.       event_process();
  1197.   }
  1198. }
  1199.  
  1200.  
  1201. int main ()
  1202. {
  1203.   BOOL cmos_changed;
  1204.  
  1205.   res_init("CheckCMOS");
  1206.   msgs_init();
  1207.   read_cmos (¤t_cmos);
  1208.   if (!file_exists(CMOS_preferences))
  1209.     save_cmos_preferences (current_cmos);
  1210.   else
  1211.     {
  1212.       read_cmos_preferences (&preferred_cmos);
  1213.       perform_cmos_check(&cmos_changed);
  1214.       if (cmos_changed)
  1215.         alert_user_of_changes ();
  1216.     }
  1217.  
  1218.   return 0;
  1219. }
  1220.